package uebung07_h;

import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import tools.ColorConversions;
import tools.Image;
import tools.ShowImage;

public class Guttenberg03 {
	public static void main(String[] args) throws Exception {
		
		BufferedImage bim1 = ImageIO.read(Guttenberg03.class.getClassLoader().getResourceAsStream("res/im2.png"));
		BufferedImage bim2 = ImageIO.read(Guttenberg03.class.getClassLoader().getResourceAsStream("res/im6.png"));
		
		int[] im1 = bim1.getRGB(0, 0, bim1.getWidth(), bim1.getHeight(), new int[bim1.getWidth()*bim1.getHeight()], 0, bim1.getWidth());
		int[] im2 = bim2.getRGB(0, 0, bim2.getWidth(), bim2.getHeight(), new int[bim2.getWidth()*bim2.getHeight()], 0, bim2.getWidth());
		
		int[] im1r = new int[bim1.getWidth()*bim1.getHeight()], im1g = new int[bim1.getWidth()*bim1.getHeight()], im1b = new int[bim1.getWidth()*bim1.getHeight()];
		int[] im2r = new int[bim2.getWidth()*bim2.getHeight()], im2g = new int[bim2.getWidth()*bim2.getHeight()], im2b = new int[bim2.getWidth()*bim2.getHeight()];
		
		for (int i = 0; i<im1.length; i++) {
			{
				int temp = im1[i], r = (temp>>16)&0xFF, g = (temp>>8)&0xFF, b = temp&0xFF;
				im1r[i] = r;
				im1g[i] = g;
				im1b[i] = b;
			}
			{
				int temp = im2[i], r = (temp>>16)&0xFF, g = (temp>>8)&0xFF, b = temp&0xFF;
				im2r[i] = r;
				im2g[i] = g;
				im2b[i] = b;
			}
		}
		
		int win = 5, im1w = bim1.getWidth(), im2w = bim2.getWidth(), im1h = bim1.getHeight(), im2h = bim2.getHeight();

		double[] disparityMap = new double[im1w*im1h];
		boolean[] mrf = new boolean[im1w*im1h];
		
		int dispmin = 0, dispmax = 64; 
		double[] sums = new double[dispmax];
		double threshold = 500000;
		
		for (int y = win, endy = im1h-win; y<endy; y++) {
			for (int x = win, endx = im1w-win; x<endx; x++) {
				for (int disparity = 0; disparity<dispmax; disparity++) {
					double sum = 0;
					for (int a = -win; a<win; a++) {
						for (int b = -win; b<win; b++) {
							if (x+b+disparity<im1w) {
								int r1 = im1[x+b+(y+a)*im1w], rshift = im2[x+b+(y+a)*im1w+disparity];
								int g1 = im1[x+b+(y+a)*im1w], gshift = im2[x+b+(y+a)*im1w+disparity];
								int b1 = im1[x+b+(y+a)*im1w], bshift = im2[x+b+(y+a)*im1w+disparity];
								double cross = r1*rshift+g1*gshift+b1*bshift, fore = r1*r1+g1*g1+b1*b1, back = rshift*rshift+gshift*gshift+bshift*bshift;
								double d = (fore+back-Math.sqrt((fore-back)*(fore-back)+4*cross*cross))/2;
								boolean ftbt = (fore-threshold)*(back-threshold) > cross*cross, fb = fore+back>2*threshold;
								sum += d;
								mrf[x+y*im1w] = ftbt&&fb;
							}
							else {
								sum += 0;
							}
						}
					}
					sums[disparity] = sum;
				}
				double max = Double.NEGATIVE_INFINITY;
				
				int mindisparity = 0;
				
				for (int i = 0; i<dispmax; i++) {
					if (max>sums[i]) {
						max = sums[i];
						mindisparity = i;
					}
				}

				if (max>threshold)
					disparityMap[x+y*im1w] = dispmax-mindisparity;
				else
					disparityMap[x+y*im1w] = dispmax;
			} 
		}
		
		JFrame ff = new JFrame();
		ff.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		final BufferedImage bi = new BufferedImage(im1w, im1h, BufferedImage.TYPE_INT_ARGB);
		
		int[] pixels = Image.prepare(disparityMap, new int[im1w*im1h]);
		int[] poxels = Image.buildRGB(pixels, pixels, pixels, new int[disparityMap.length]);
	
 		bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), poxels, 0, bi.getWidth());
		ff.add(new ShowImage(bi));
		
		ff.pack();
		ff.setVisible(true);
	}
}
